package com.yict.csms.company.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yict.common.entity.PageEntity;
import com.yict.common.service.impl.CommonService;
import com.yict.common.util.DateUtil;
import com.yict.csms.company.dao.impl.CompanyDaoImpl;
import com.yict.csms.company.entity.Company;
import com.yict.csms.company.service.ICompanyService;
import com.yict.csms.system.dao.impl.CostProfessionDaoImpl;
import com.yict.csms.system.entity.CostProfession;

/**
 * 
 * 
 * @author Patrick.Deng
 * 
 */
@Service
public class CompanyServiceImpl extends CommonService<Company, Long> implements
		ICompanyService {
	@Autowired
	private CompanyDaoImpl companyDaoImpl;
	
	@Autowired
	private CostProfessionDaoImpl costProfessionDaoImpl;

	public List<Company> findAllList(Map<String, Object> queryMap,
			PageEntity page) {
		StringBuilder queryString = new StringBuilder();
		pageEntity = new PageEntity();
		queryString.append(" from Company as c where 1=1 and c.deleted = 0");
		if (queryMap != null && queryMap.size() > 0) {
			if (queryMap.get("companyIdList") != null && !"".equals(queryMap.get("companyIdList"))) {
				queryString.append(" and c.companyId in (:companyIdList)");
			}
			if (queryMap.get("companyName") != null && !"".equals(queryMap.get("companyName"))) {
				queryString.append(" and lower(c.companyName) like :companyName");
				queryMap.put("companyName", queryMap.get("companyName").toString().toLowerCase());
			}
			if (queryMap.get("contractTypeIdList") != null && !"".equals(queryMap.get("contractTypeIdList"))) {
				queryString
						.append(" and c.companyId in (select t.company.companyId from Contract t where t.contractType.typeId in(:contractTypeIdList))");
			}
		}
		queryString.append(this.changeOrder(page));
		List<Company> list = companyDaoImpl.search(queryString.toString(), queryMap, page);
		pageEntity.setTotalRecord(companyDaoImpl.getPageEntity().getTotalRecord());
		return list;
	}

	public List<Company> search(Map<String, Object> queryMap,
			PageEntity page) {
		StringBuilder queryString = new StringBuilder();
		pageEntity = new PageEntity();
		queryString.append(" from Company as c where 1=1 and c.deleted = 0 and c.companyType != 1");
		if (queryMap != null && queryMap.size() > 0) {
			if (queryMap.get("companyIdList") != null && !"".equals(queryMap.get("companyIdList"))) {
				queryString.append(" and c.companyId in (:companyIdList)");
			}
			if (queryMap.get("companyName") != null && !"".equals(queryMap.get("companyName"))) {
				queryString.append(" and lower(c.companyName) like :companyName");
				queryMap.put("companyName", queryMap.get("companyName").toString().toLowerCase());
			}
			if (queryMap.get("contractTypeIdList") != null && !"".equals(queryMap.get("contractTypeIdList"))) {
				queryString
						.append(" and c.companyId in (select t.company.companyId from Contract t where t.contractType.typeId in(:contractTypeIdList))");
			}
		}
		queryString.append(this.changeOrder(page));
		List<Company> list = companyDaoImpl.search(queryString.toString(),
				queryMap, page);
		pageEntity.setTotalRecord(companyDaoImpl.getPageEntity()
				.getTotalRecord());
		return list;
	}
	
	/**
	 * 查找有合同有效日期包含制定日期的公司
	 * 
	 * @param date
	 * @return
	 */
	public List<Company> queryByContractDate(Date date) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("cpdate", date);
		StringBuilder queryString = new StringBuilder();
		queryString
				.append("select c from Company as c inner join c.contractSet t where  c.deleted = 0 and t.effectiveDate < :cpdate and t.expirationDate > :cpdate");
		List<Company> list = companyDaoImpl.search(queryString.toString(), map,
				null);
		return list;
	}

	public List<Company> queryByContractDate(HashMap<String, Object> map,
			PageEntity page) {
		pageEntity = new PageEntity();
		StringBuilder queryString = new StringBuilder();
		queryString
				.append("select c from Company as c inner join c.contractSet as t inner join t.contractRateSet as r where  c.deleted = 0 and r.effectiveDate <= to_date(:cpdate,'yyyy-MM-dd') and r.expirationDate >= to_date(:cpdate,'yyyy-MM-dd') and r.profession.profetype = :profetype and r.ratestutas='Y'");
		List<Company> list = companyDaoImpl.search(queryString.toString(), map,
				page);
		pageEntity.setTotalRecord(companyDaoImpl.getPageEntity()
				.getTotalRecord());
		return list;
	}

	public LinkedHashMap<String, String> getCompanyNameMap() {
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
		StringBuilder queryString = new StringBuilder();
		queryString.append(" from Company as c where c.deleted=0 order by c.createDate desc");
		List<Company> list = companyDaoImpl.search(queryString.toString(),
				null, null);
		if (list != null) {
			for (Company company : list) {
				map.put(company.getCompanyId().toString(),
						company.getCompanySName());
			}
		}
		return map;
	}
    //过滤公司只有RTGC和FL工种
	public LinkedHashMap<String, String> getCompanyNameMap(HashMap<String, Object> queryMap) {
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
		StringBuilder queryString = new StringBuilder();
		queryString.append("select c from Company as c inner join c.contractSet as s left join s.contractRateSet as r where  c.deleted = 0  and (r.profession.profecode = :profetype_rtgc or r.profession.profecode = :profetype_fl) and r.ratestutas='Y' order by c.createDate desc");
		List<Company> list = companyDaoImpl.search(queryString.toString(),
				queryMap, null);
		if (list != null) {
			for (Company company : list) {
				map.put(company.getCompanyId().toString(),
						company.getCompanySName());
			}
		}
		return map;
	}
	/**
	 * 存在工种的承包商
	 * **/
	public List<Company> getCompanyList(HashMap<String, Object> queryMap) {
		StringBuilder queryString = new StringBuilder();
		Date date = new Date();
		String str = DateUtil.DateToString(date, 1);
		queryString.append("select c from Company as c inner join c.contractSet as s left join s.contractRateSet as r left join r.profession.costProfessionCost as p " +
				"left join p.orderProfeid as p1 "+
				"where  c.deleted = 0 and (r.profession.profecode = :type01 or p1.profecode = :type01) and r.effectiveDate <= to_date('"+str+"','yyyy-mm-dd') " +
				"and r.expirationDate >= to_date('"+str+"','yyyy-mm-dd') and r.ratestutas='Y' order by c.createDate desc");
		List<Company> list = companyDaoImpl.search(queryString.toString(),
				queryMap, null);
		return list;
	}
	
	public Company findById(Long id) {
		return companyDaoImpl.findById(id);
	}

	private String changeOrder(PageEntity entity) {
		String str = " order by c.";
		if (entity != null && entity.getField() != null
				&& !entity.getField().equals("")) {
			if (entity.getField().equals("companySName"))
				str += "companySName ";
			else if (entity.getField().equals("companyName"))
				str += "companyName ";
			else if (entity.getField().equals("license"))
				str += "license ";
			else if (entity.getField().equals("endBussDate"))
				str += "endBussDate ";
			else if (entity.getField().equals("legalPerson"))
				str += "legalPerson ";
			else if (entity.getField().equals("address"))
				str += "address ";
			else if (entity.getField().equals("website"))
				str += "website ";
			else if (entity.getField().equals("tel"))
				str += "tel ";
			else if (entity.getField().equals("fax"))
				str += "fax ";
			else if (entity.getField().equals("payBank"))
				str += "payBank ";
			else if (entity.getField().equals("payBankNum"))
				str += "payBankNum ";
			else
				str += "createDate desc";
			str += entity.getOrder();
		} else {
			str += "createDate desc";
		}
		return str;
	}
	
	/**
	 * 根据id查找实体
	 * @param ids
	 * @return
	 */
	public List<Company> listByIds(Collection<Long> ids){
		if(ids == null || ids.size() == 0) return new ArrayList<Company>();
		String hql = "from Company t where companyId in (:ids)";
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("ids", ids);
		List<Company> list;
		try {
			list = companyDaoImpl.search(hql,map, null);
		} catch (Exception e) {
			list = new ArrayList<Company>();
		}
		return list;
	}

	/**
	 * 根据相应的类型、Id查找公司
	 * 
	 * @param id
	 *            - typeId , profeId
	 * @param type
	 *            -contract ， profe
	 * @param profeDate
	 * 			 - 有效日期
	 * @return
	 */
	public LinkedHashMap<String, String> getCompanyNameMap(Long id, String type, String profeDate) {
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
		StringBuilder queryString = new StringBuilder();
		Map<String, Object> queryMap = null;
		if (type != null && type.equals("contract")) {
			queryString
					.append(" from Company as a where a.companyId in ( select b.company.companyId from Contract c, "
							+ "ContractRate b where c.contractId = b.contract.contractId and c.contractType.typeId ="
							+ id + ") and a.deleted = 0 and a.companyType != 1");
		}
		if (type != null && type.equals("profe")) {
			List<Long> ids = new ArrayList<Long>();
			List<CostProfession> costPro = costProfessionDaoImpl.findByOProId(id);
			if(costPro != null && costPro.size() > 0) {
				for (CostProfession costProfession : costPro) {
					ids.add(costProfession.getCostProfeid().getProfeid());
				}
			} else {
				ids.add(id);
			}
			queryMap = new HashMap<String, Object>();
			if(ids.size() > 1) {
				queryString.append(" from Company as a where a.companyId in (select t.company.companyId from ContractRate t" +
						" where t.company.companyId in ( select b.company.companyId from ContractRate b, Contract c "
						+ " where b.contract.contractId = c.contractId and b.ratestutas = 'Y' and b.profession.profeid in (:ids0) " +
				" and t.profession.profeid in (:ids1)");
				queryMap.put("ids0", ids.get(0));
				queryMap.put("ids1", ids.get(1));
			} else {
				queryString.append(" from Company as a where a.companyId in (select b.company.companyId from ContractRate b, Contract c "
						+ "where b.contract.contractId = c.contractId and b.ratestutas = 'Y' and b.profession.profeid in (:ids) ");
				queryMap.put("ids", ids);
			}
			if(profeDate == null) {
				queryString.append(" and b.effectiveDate <= to_date('" + DateUtil.DateToString(new Date(), 1) + "','yyyy-MM-dd') " +
						"and b.expirationDate >= to_date('" + DateUtil.DateToString(new Date(), 1) + "','yyyy-MM-dd')");
			} else {
				queryString.append(" and b.effectiveDate <= to_date('" + profeDate + "','yyyy-MM-dd') " +
						"and b.expirationDate >= to_date('" + profeDate + "','yyyy-MM-dd')");
			}
			if(ids.size() > 1) {
				queryString.append(")");
			}
			queryString.append(") and a.deleted = '0' and a.companyType != 1");
		}
		List<Company> list = companyDaoImpl.search(queryString.toString(),
				queryMap, null);
		if (list != null) {
			for (Company company : list) {
				map.put(company.getCompanyId().toString(),
						company.getCompanySName());
			}
		}
		return map;
	}

	public List<Company> findByProfeAndOrderdate(Long pid, Date cpdate) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("cpdate", cpdate);
		map.put("profeid", pid);
		map.put("ratestutas", "Y");
		String hql = "select t1.contract.company from ContractRate as t1 where t1.profession.profeid = :profeid" +
				" and t1.effectiveDate <= :cpdate and t1.expirationDate >= :cpdate and t1.ratestutas=:ratestutas";
		List<Company> list = companyDaoImpl.search(hql, map, null);
		return list;
	}

	/**
	 * 是否存在 相同的 承包商简称、名称、代码
	 * @param company
	 * @param isSave
	 * @return
	 */
	public String check(Company company, boolean isSave) {
		String result = "";
		StringBuilder queryString = new StringBuilder();
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryString.append("from Company as c where 1=1 and upper(c.companySName) =:companySName and c.deleted = 0");
		queryMap.put("companySName", company.getCompanySName().toUpperCase());
		if(!isSave) {
			queryString.append(" and c.companyId not in (:companyId)");
			queryMap.put("companyId", company.getCompanyId());
		}
		List<Company> list =  companyDaoImpl.search(queryString.toString(),queryMap,null);
		if (list != null && list.size() > 0) {
			result += "承包商简称必须唯一";
		}
		
		StringBuilder queryString2 = new StringBuilder();
		Map<String, Object> queryMap2 = new HashMap<String, Object>();
		queryString2.append("from Company as c where 1=1 and upper(c.companyName) =:companyName and c.deleted = 0");
		queryMap2.put("companyName", company.getCompanyName().toUpperCase());
		if(!isSave) {
			queryString2.append(" and c.companyId not in (:companyId)");
			queryMap2.put("companyId", company.getCompanyId());
		}
		List<Company> list2 =  companyDaoImpl.search(queryString2.toString(),queryMap2,null);
		if (list2 != null && list2.size() > 0) {
			result += " 承包商名称必须唯一";
		}
		
		if(company.getCompanyCode() != null && !company.getCompanyCode().equals("")) {
			StringBuilder queryString3 = new StringBuilder();
			Map<String, Object> queryMap3 = new HashMap<String, Object>();
			queryString3.append("from Company as c where 1=1 and c.companyCode = :companyCode and c.deleted = 0");
			queryMap3.put("companyCode", company.getCompanyCode());
			if(!isSave) {
				queryString3.append(" and c.companyId not in (:companyId)");
				queryMap3.put("companyId", company.getCompanyId());
			}
			List<Company> list3 =  companyDaoImpl.search(queryString3.toString(),queryMap3,null);
			if (list3 != null && list3.size() > 0) {
				result += " 承包商代码必须唯一";
			}
		}
		return result;
	}
	
	/**
	 * 根据单个属性查找
	 * @param value
	 * @param propertyName
	 * @return
	 */
	public List<Company> listByProperty(Object value,String propertyName){
		List<Company> list = new ArrayList<Company>();
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(propertyName, value);
		try {
			list = companyDaoImpl.list(map, null, 0, 0);
		} catch (Exception e) {
			//logger.info(e);
		}
		return list;
	}
	
	/**
	 * 根据属性查找唯一记录
	 * @param value
	 * @param propertyName
	 * @return
	 * @throws Exception
	 */
	public Company findByUnique(Object value,String propertyName) {
		Company vo = null;
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(propertyName, value);
		List<Company> list = companyDaoImpl.list(map, null, 0, 0);
		if(list.size() > 1) 
			throw new RuntimeException("与期望的唯一记录不一致，找到多个记录:" + propertyName + "=" + value);
		if(list.size() == 1) vo = list.get(0);
		return vo;
	}
}
